package mylab.io.base.util;

import com.google.common.base.Preconditions;

import cn.hutool.core.text.CharSequenceUtil;
import lombok.experimental.UtilityClass;
import lombok.extern.slf4j.Slf4j;
import mylab.io.base.model.BaseMsg;
import mylab.io.base.model.Msg;
import mylab.io.base.model.MsgType;
import mylab.io.base.model.Terminal;
import mylab.utils.common.CastUtil;
import mylab.utils.common.ReflectUtil;
import mylab.utils.common.jackson.JacksonUtil;

@Slf4j
@UtilityClass
public class MsgUtil {

    public Msg newMsg(String msgCode) {
        return newMsg(Msg.class, null, null, msgCode, MsgType.Undefined);
    }

    public <T extends Msg> T newMsg(Class<T> msgClass, String msgCode) {
        return newMsg(msgClass, null, null, msgCode, MsgType.Undefined);
    }

    public <T extends Msg> T newMsg(Class<T> msgClass, Terminal remote, String msgCode) {
        return newMsg(msgClass, null, remote, msgCode, MsgType.Undefined);
    }

    public <T extends Msg> T newMsg(Class<T> msgClass, Terminal from, Terminal to, String msgCode, MsgType msgType) {
        T msg = ReflectUtil.newInstance(msgClass);
        msg.setCode(msgCode);
        msg.setType(msgType);
        msg.setFrom(from);
        msg.setTo(to);
        return msg;
    }

    public <T extends Msg> T replyMsg(T request, String responseMsgCode) {
        Object response = newMsg(request.getClass(), request.getFrom(), responseMsgCode);
        return CastUtil.cast(response);
    }


    public boolean isValid(Msg msg) {
        Preconditions.checkNotNull(msg, "msg is null");
        Preconditions.checkState(CharSequenceUtil.isNotEmpty(msg.getCode()), "code of msg is null");
        return true;
    }

    public static void main(String[] args) {
        BaseMsg request = newMsg(BaseMsg.class, "101");
        request.setFrom(TerminalUtil.socketTerminal("192.168.1.101", 2000));

        BaseMsg response = replyMsg(request, "202");
        log.info(JacksonUtil.toJsonString(response));

        response = request.reply("202");
        log.info(JacksonUtil.toJsonString(response));
    }
}
